﻿#include "widget.h"
#include "ui_widget.h"
#include <vector>
#include <QDebug>

using std::vector;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget), video(0)
{
    ui->setupUi(this);
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &Widget::updatePicture);
    timer->start(100);  //每秒钟检测10帧
    ui->label->setScaledContents(true);
    //创建级联分类器，并加载模型文件
    classifier = new cv::CascadeClassifier("/home/student/opencv/haarcascade_frontalface_alt.xml");
    bdf = new BaiduFace("kIGVsMnZEKqCfLfnl9op20cq", "udOcOUcZ1sRVG40sHTm5x4FzjiUxmpUh", this);
    connect(bdf, &BaiduFace::found, this, &Widget::faceFound);

    groups = "group1";
}

void Widget::detectFace(cv::Mat& img)
{
    static int punch; //累计连续检测成功次数，如果等于10次则开始进行识别
    cv::Mat gray(img.size(), CV_8UC1);
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    cv::equalizeHist(gray, gray);

    vector<cv::Rect> objects;
    classifier->detectMultiScale(gray, objects);
    if (objects.size())
    {
        punch++;
        cv::rectangle(img, objects[0], CV_RGB(255,0,0));  //仅检测一张脸
        if (punch == 10) //开始识别
        {
            cv::Mat roi(img, objects[0]);     //裁剪图片
            //cv::imwrite("faceroi.jpg", roi);  //将裁剪后的图片转换格式并写入文件
            //qDebug() << "do recognition";
            vector<uchar> buf;
            cv::imencode(".jpg", roi, buf);    //将裁剪后的图片转换格式并写入内存
            bdf->search(QByteArray::fromRawData((char*)buf.data(), buf.size()), groups);  //将图片编码为Base64字符串
        }
    }
    else
    {
        punch = 0;
    }
}

void Widget::faceFound()
{
    qDebug() << bdf->userid();
}

void Widget::updatePicture()
{
    cv::Mat image;
    video >> image;  //采集一帧图像
    detectFace(image);
    cv::cvtColor(image, image, CV_BGR2RGB);   //将OpenCV的Mat数据结构转换为QImage
    ui->label->setPixmap(QPixmap::fromImage(QImage(image.data, image.cols, image.rows, image.step, QImage::Format_RGB888)));
}

Widget::~Widget()
{
    delete ui;
}
